package com.gite.nouette.admin.implementation.integrator.factory;

import com.gite.nouette.admin.contract.controller.ICAdmin;
import com.gite.nouette.admin.contract.controller.ICContainerModule;
import com.gite.nouette.admin.contract.controller.ICHandlerModule;
import com.gite.nouette.admin.contract.controller.ICManager;
import com.gite.nouette.admin.contract.controller.command.ICCommandCreateModule;
import com.gite.nouette.admin.contract.controller.command.ICCommandModule;
import com.gite.nouette.admin.contract.controller.command.ICCommandRemoveModule;
import com.gite.nouette.admin.contract.controller.module.ICModuleError;
import com.gite.nouette.admin.contract.controller.module.ICModuleLog;
import com.gite.nouette.admin.contract.integrator.factory.IFactoryController;
import com.gite.nouette.admin.contract.integrator.factory.IFactoryModel;
import com.gite.nouette.admin.contract.integrator.factory.IFactoryView;
import com.gite.nouette.admin.contract.model.IAdmin;
import com.gite.nouette.admin.contract.model.ICommand;
import com.gite.nouette.admin.contract.model.IContainerModule;
import com.gite.nouette.admin.contract.model.IHandlerModule;
import com.gite.nouette.admin.contract.model.IManager;
import com.gite.nouette.admin.contract.model.command.ICommandCreateModule;
import com.gite.nouette.admin.contract.model.command.ICommandModule;
import com.gite.nouette.admin.contract.model.command.ICommandRemoveModule;
import com.gite.nouette.admin.contract.model.command.IStateCommandActivation;
import com.gite.nouette.admin.contract.model.module.IModuleError;
import com.gite.nouette.admin.contract.model.module.IModuleLog;
import com.gite.nouette.admin.contract.observer.IObservable;
import com.gite.nouette.admin.implementation.controller.CAdminImpl;
import com.gite.nouette.admin.implementation.controller.CContainerModuleImpl;
import com.gite.nouette.admin.implementation.controller.CHandlerModuleImpl;
import com.gite.nouette.admin.implementation.controller.CManagerImpl;
import com.gite.nouette.admin.implementation.controller.command.CCommandCreateModuleImpl;
import com.gite.nouette.admin.implementation.controller.command.CCommandRemoveModuleImpl;
import com.gite.nouette.admin.implementation.controller.module.CModuleErrorImpl;
import com.gite.nouette.admin.implementation.controller.module.CModuleLogImpl;

public class FactoryControllerImpl implements IFactoryController {
	private IFactoryModel factoryModel;
	private IFactoryView factoryView;

	@Override
	public IAdmin getAdmin() {
		return getCAdmin();
	}

	@Override
	public IContainerModule getContainerModule() {
		return getCContainerModule();
	}

	@Override
	public IHandlerModule getHandlerModule() {
		return getCHandlerModule();
	}

	@Override
	public IManager getManager() {
		return getCManager();
	}

	@Override
	public IModuleLog getModuleLog(ICommandModule... headerCommands) {
		ICCommandModule<?, ?>[] cHeaderCommands = getCCommandModules(headerCommands);
		return getCModuleLog(cHeaderCommands);
	}

	@Override
	public IModuleError getModuleError(ICommandModule... headerCommands) {
		ICCommandModule<?, ?>[] cHeaderCommands = getCCommandModules(headerCommands);
		return getCModuleError(cHeaderCommands);
	}

	@Override
	public ICommandCreateModule getCommandCreateModule() {
		return getCCommandCreateModule();
	}

	@Override
	public ICommandRemoveModule getCommandRemoveModule() {
		return getCCommandRemoveModule();
	}

	@Override
	public IStateCommandActivation getStateCommandActive() {
		return getFactoryModel().getStateCommandActive();
	}

	@Override
	public IStateCommandActivation getStateCommandDesactive() {
		return getFactoryModel().getStateCommandDesactive();
	}

	@Override
	public <O> IObservable<O> getObservable(O o) {
		return getFactoryModel().getObservable(o);
	}

	@Override
	public IObservable<ICommand> getObservableCommand(ICommand command) {
		return getFactoryModel().getObservableCommand(command);
	}

	@Override
	public IFactoryModel getFactoryModel() {
		return this.factoryModel;
	}

	@Override
	public void setFactoryModel(IFactoryModel factoryModel) {
		this.factoryModel = factoryModel;
	}

	@Override
	public IFactoryView getFactoryView() {
		return this.factoryView;
	}

	@Override
	public void setFactoryView(IFactoryView factoryView) {
		this.factoryView = factoryView;
	}

	@Override
	public ICAdmin getCAdmin() {
		return createCAdmin();
	}

	private ICAdmin createCAdmin() {
		ICAdmin cAdmin = new CAdminImpl();
		cAdmin.setM(getFactoryModel().getAdmin());
		cAdmin.setV(getFactoryView().getVAdmin());
		cAdmin.getV().setC(cAdmin);
		cAdmin.init();

		return cAdmin;
	}

	@Override
	public ICManager getCManager() {
		return createCManager();
	}

	private ICManager createCManager() {
		ICManager cManager = new CManagerImpl();
		cManager.setM(getFactoryModel().getManager());
		cManager.setV(getFactoryView().getVManager());
		cManager.getV().setC(cManager);
		cManager.init();

		return cManager;
	}

	@Override
	public ICHandlerModule getCHandlerModule() {
		return createCHandlerModule();
	}

	private ICHandlerModule createCHandlerModule() {
		ICHandlerModule cHandlerModule = new CHandlerModuleImpl();
		cHandlerModule.setM(getFactoryModel().getHandlerModule());
		cHandlerModule.setV(getFactoryView().getVHandlerModule());
		cHandlerModule.getV().setC(cHandlerModule);
		cHandlerModule.init();

		return cHandlerModule;
	}

	@Override
	public ICContainerModule getCContainerModule() {
		return createCContainerModule();
	}

	private ICContainerModule createCContainerModule() {
		ICContainerModule cContainerModule = new CContainerModuleImpl();
		cContainerModule.setM(getFactoryModel().getContainerModule());
		cContainerModule.setV(getFactoryView().getVContainerModule());
		cContainerModule.getV().setC(cContainerModule);
		cContainerModule.init();

		return cContainerModule;
	}

	@Override
	public ICModuleLog getCModuleLog(ICCommandModule<?, ?>... headerCCommands) {
		return createCModuleLog(headerCCommands);
	}

	private ICModuleLog createCModuleLog(
			ICCommandModule<?, ?>... headerCCommands) {
		ICModuleLog cModuleLog = new CModuleLogImpl();
		cModuleLog.setM(getFactoryModel().getModuleLog(headerCCommands));
		cModuleLog.setV(getFactoryView().getVModuleLog(
				cModuleLog.getHeaderVCommands()));
		cModuleLog.getV().setC(cModuleLog);
		cModuleLog.init();

		return cModuleLog;
	}

	@Override
	public ICModuleError getCModuleError(
			ICCommandModule<?, ?>... headerCCommands) {
		return createCModuleError(headerCCommands);
	}

	private ICModuleError createCModuleError(
			ICCommandModule<?, ?>... headerCCommands) {
		ICModuleError cModuleError = new CModuleErrorImpl();
		cModuleError.setM(getFactoryModel().getModuleError(headerCCommands));
		cModuleError.setV(getFactoryView().getVModuleError(
				cModuleError.getHeaderVCommands()));
		cModuleError.getV().setC(cModuleError);
		cModuleError.init();

		return cModuleError;
	}

	@Override
	public ICCommandCreateModule getCCommandCreateModule() {
		return createCCommandCreateModule();
	}

	private ICCommandCreateModule createCCommandCreateModule() {
		ICCommandCreateModule cCommandCreateModule = new CCommandCreateModuleImpl();
		cCommandCreateModule.setM(getFactoryModel().getCommandCreateModule());
		cCommandCreateModule.setV(getFactoryView().getVCommandCreateModule());
		cCommandCreateModule.getV().setC(cCommandCreateModule);
		cCommandCreateModule.init();

		return cCommandCreateModule;
	}

	@Override
	public ICCommandRemoveModule getCCommandRemoveModule() {
		return createCCommandRemoveModule();
	}

	private ICCommandRemoveModule createCCommandRemoveModule() {
		ICCommandRemoveModule cCommandRemoveModule = new CCommandRemoveModuleImpl();
		cCommandRemoveModule.setM(getFactoryModel().getCommandRemoveModule());
		cCommandRemoveModule.setV(getFactoryView().getVCommandRemoveModule());
		cCommandRemoveModule.getV().setC(cCommandRemoveModule);
		cCommandRemoveModule.init();

		return cCommandRemoveModule;
	}

	/* UTILS */

	private ICCommandModule<?, ?>[] getCCommandModules(
			ICommandModule... commandModules) {
		ICCommandModule<?, ?>[] cCommandModules = new ICCommandModule[commandModules.length];
		int i = 0;
		for (ICommandModule commandModule : commandModules) {
			cCommandModules[i] = (ICCommandModule<?, ?>) commandModule;
			i++;
		}
		return cCommandModules;
	}
}
